#pragma once

#ifndef __CORE_hash_funcs_H__
#define __CORE_hash_funcs_H__

#include "FLOW_core/core_types.h"
#include "FLOW_core/namespace.h"
#include <cstring>

/*!
 * \brief Declaration of the hash function used in the FLOW project
 *
 * Declaration of the hash function used in the FLOW project
 */

#define FLOW_Hash_Function		MurmurHash3_x86_32

namespace CORE
{
	//! typedef to name unsigned integer used as hash values
	typedef u32_t	hashid_t;

	/*!
	 * \brief MurmurHash function in its version returning a 32 bit value tailored for x86 machines
	 *
	 * MurmurHash function in its version returning a 32 bit value tailored for x86 machines. All credits
	 * to Austin Appleby. Code extracted from http://code.google.com/p/smhasher/ under the MIT license terms.
	 */
	hashid_t MurmurHash3_x86_32( const void* ap_key, int len, hashid_t seed );

	/*!
	 * \brief Wrapper class to use MurmurHash3_x86_32 with hash containers
	 *
	 * Wrapper class to use MurmurHash3_x86_32 with hash containers
	 */
	template< typename HashedType >
	struct FlowHasher
	{
	};

	template< >
	struct FlowHasher< char_t* >
	{
		size_t operator( )( const char_t* psz ) const
		{
			return static_cast< size_t >( MurmurHash3_x86_32( psz, strlen( psz ), 0 ) );
		}
	};

	template< >
	struct FlowHasher< const char_t* >
	{
		size_t operator( )( const char_t* psz ) const
		{
			return static_cast< size_t >( MurmurHash3_x86_32( psz, strlen( psz ), 0 ) );
		}
	};

	template< >
	struct FlowHasher< s8_t >
	{
		size_t operator( )( s8_t x ) const
		{ 
			return x;
		}
	};

	template< >
	struct FlowHasher< u8_t >
	{
		size_t operator( )( u8_t x ) const
		{ 
			return x;
		}
	};

	template< >
	struct FlowHasher< s16_t >
	{
		size_t operator( )( s16_t x ) const
		{ 
			return x;
		}
	};

	template< >
	struct FlowHasher< u16_t >
	{
		size_t operator( )( u16_t x ) const
		{ 
			return x;
		}
	};

	template< >
	struct FlowHasher< int_t >
	{
		size_t operator( )( int_t x ) const
		{ 
			return x;
		}
	};

	template< >
	struct FlowHasher< uint_t >
	{
		size_t operator( )( uint_t x ) const
		{ 
			return x;
		}
	};

	template< >
	struct FlowHasher< long_t >
	{
		size_t operator( )( long_t x ) const
		{ 
			return x;
		}
	};

	template< >
	struct FlowHasher< ulong_t >
	{
		size_t operator( )( ulong_t x ) const
		{ 
			return x;
		}
	};

	template< >
	struct FlowHasher< void* >
	{
		union vp 
		{
			size_t		s;
			void*		p;
		};

		size_t operator( )( void* p ) const
		{
		   vp u_vp;
		   u_vp.p = p;
		   return u_vp.s;
		}
	};

} //namespace CORE

#endif